package fun.easycode.datastream;

import cn.hutool.core.util.ReflectUtil;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.override.MybatisMapperProxy;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 动态数据源拦截器
 * @author xuzhen97
 */
@Slf4j
public class DynamicDatasourceInterceptor implements MethodInterceptor {

    /**
     * dao包名正则, 用于提取数据源名称
     */
    private static final Pattern DATASOURCE_PATTERN = Pattern.compile("(?<=dao\\.).*(?=\\..*)");

    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {

        Object proxyObj = methodInvocation.getThis();
        MybatisMapperProxy<?> mybatisMapperProxy =
                (MybatisMapperProxy<?>) ReflectUtil.getFieldValue(proxyObj, "h");
        Class<?> mapperInterface = (Class<?>) ReflectUtil.getFieldValue(mybatisMapperProxy, "mapperInterface");

        // 如果不是继承自BaseMapper, 则不处理
        if(mapperInterface == null){
            return methodInvocation.proceed();
        }

        Matcher matcher = DATASOURCE_PATTERN.matcher(mapperInterface.getCanonicalName());

        if (matcher.find()) {
            // 切换数据源
            DynamicDataSourceContextHolder.push(matcher.group());
            if(log.isDebugEnabled()){
                log.debug("切换数据源：{}", matcher.group());
            }
        }
        return methodInvocation.proceed();
    }
}
